package cn.kgc.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

/**
 * shiro安全框架的认证流程
 * 1. Subject           主体
 * 2. SecurityManager   安全管理器
 * 3. Authenticator     认证器
 * 4. Authorizer        授权器
 * 5. Realm             域对象    数据源操作
 */
public class App {

    public static void main(String[] args) {


        // 创建安全管理器对象
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        // 创建域对象   Realm  ->  IniRealm  加载.ini配置文件中的数据
        //IniRealm iniRealm = new IniRealm("classpath:users.ini");

        // 创建自定义的Realm对象
        CustomerRealm customerRealm = new CustomerRealm();
        // 创建凭证匹配器对象
        HashedCredentialsMatcher md5 = new HashedCredentialsMatcher("MD5");
        // 设置hash的次数
        md5.setHashIterations(10);
        customerRealm.setCredentialsMatcher(md5);


        // 将realm对象注入到安全管理器对象
        defaultSecurityManager.setRealm(customerRealm);

        // 安全管理工具类 注入一个安全管理器对象
        SecurityUtils.setSecurityManager(defaultSecurityManager);


        //  通过安全管理工具类 获取认证主体
        Subject subject = SecurityUtils.getSubject();
        // 将用户名和密码封装成token    AuthenticationToken    ->  实现类  UsernamePasswordToken
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("admin", "123456");

        // 认证    只要该方法不抛出异常  则认证通过     认证失败   用户名不存在   密码错误
        try {
            subject.login(usernamePasswordToken);
            // 判定用户是否认证通过
            boolean authenticated = subject.isAuthenticated();
            System.out.println("authenticated = " + authenticated);

            // 授权 判定用户是否有访问受限资源的权限  /user/add   /user/delete   1. 基于角色的判定   2.基于权限字符串的判定

            // 1.编程式权限控制   2.注解式的权限控制
            //boolean b = subject.hasRole("admin");
            //System.out.println("b = " + b);
            // 必须同时具有两个角色
            //boolean b1 = subject.hasAllRoles(Arrays.asList("admin", "super"));
            //System.out.println("b1 = " + b1);
            //if (b){
            //    System.out.println("用户信息添加或删除成功");
            //}else {
            //    System.out.println("没有权限.请联系管理员");
            //}
            //  基于权限字符串的判定   sys:user:add  sys:user:delete
            boolean permitted = subject.isPermitted("sys:user:add");
            System.out.println("permitted = " + permitted);


        }catch (UnknownAccountException e){
            System.out.println("用户名错误");
        }catch (IncorrectCredentialsException e){
            System.out.println("密码错误");
        }

    }
}
